// Zip/ArchiveFolder.cpp

#include "StdAfx.h"

#include "Agent.h"

#include "Common/String/StringConvert.h"


namespace Common
{
namespace Agent
{

static inline UINT GetCurrentFileCodePage()
{
  #ifdef UNDER_CE
  return CP_ACP;
  #else
  return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  #endif
}

void CArchiveFolderManager::LoadFormats()
{
  if (!_codecs)
  {
	_compressCodecsInfo = _codecs = new CComObject<Common::Archive::CCodecs>;
	_codecs->FinalConstruct();
	_codecs->Load();
  }
}

size_t CArchiveFolderManager::FindFormat(const CString &type)
{
  for (size_t i = 0; i < _codecs->Formats.size(); i++)
	if (type.CompareNoCase(_codecs->Formats[i].Name) == 0)
	  return i;
  return -1;
}

STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream,
	const wchar_t *filePath, const wchar_t *arcFormat,
	IFolderFolder **resultFolder, IProgress *progress)
{
  CComPtr<IArchiveOpenCallback> openArchiveCallback;
  if (progress != 0)
  {
	CComPtr<IProgress> progressWrapper = progress;
	progressWrapper->QueryInterface(__uuidof(IArchiveOpenCallback), (void **)&openArchiveCallback);
  }
  CAgent *agent = new CComObject<CAgent>();
  agent->FinalConstruct();
  CComPtr<IInFolderArchive> archive = agent;
  HRESULT hRes(agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback));
  if(S_OK != hRes)
		return hRes;
  return agent->BindToRootFolder(resultFolder);
}

/*
HRESULT CAgent::FolderReOpen(
	IArchiveOpenCallback *openArchiveCallback)
{
  return ReOpenArchive(_archive, _archiveFilePath);
}
*/


/*
STDMETHODIMP CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *extensions)
{
  *extensions = 0;
  int formatIndex = FindFormat(type);
  if (formatIndex <  0)
	return E_INVALIDARG;
  // Exts[0].Ext;
  return StringToBstr(_codecs.Formats[formatIndex].GetAllExtensions(), extensions);
}
*/

static void AddIconExt(const Common::Archive::CCodecIcons &lib, CString &dest)
{
  for (size_t j = 0; j < lib.IconPairs.size(); j++)
  {
	if (!dest.IsEmpty())
	  dest += _T(' ');
	dest += lib.IconPairs[j].Ext;
  }
}

STDMETHODIMP CArchiveFolderManager::GetExtensions(BSTR *extensions)
{
  LoadFormats();
  *extensions = 0;
  CString res;
  for (size_t i = 0; i < _codecs->Libs.size(); i++)
	AddIconExt(_codecs->Libs[i], res);
  AddIconExt(_codecs->InternalIcons, res);
  return StringToBstr(res, extensions);
}

STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, INT32 *iconIndex)
{
  LoadFormats();
  *iconPath = 0;
  *iconIndex = 0;
  for (size_t i = 0; i < _codecs->Libs.size(); i++)
  {
	const Common::Archive::CCodecLib &lib = _codecs->Libs[i];
	int ii;
	if (lib.FindIconIndex(ext, ii))
	{
	  *iconIndex = ii;
	  return StringToBstr(String::GetUnicodeString(lib.Path, GetCurrentFileCodePage()), iconPath);
	}
  }
  int ii;
  if (_codecs->InternalIcons.FindIconIndex(ext, ii))
  {
	*iconIndex = ii;
	CString path;
	Common::System::DLL::GetModuleFileName(_AtlBaseModule.GetModuleInstance(), path);
	return StringToBstr(path, iconPath);
  }
  return S_OK;
}

/*
STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
{
  LoadFormats();
  CString typesStrings;
  for(int i = 0; i < _codecs.Formats.Size(); i++)
  {
	const CArcInfoEx &ai = _codecs.Formats[i];
	if (ai.AssociateExts.Size() == 0)
	  continue;
	if (i != 0)
	  typesStrings += _T(' ');
	typesStrings += ai.Name;
  }
  return StringToBstr(typesStrings, types);
}
STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * type,
	const wchar_t * filePath, IProgress progress)
{
  return E_NOTIMPL;
}
*/

}}